﻿namespace Neovolve.Extensibility.ReSharper
{
    using System;
    using JetBrains.DocumentModel;
    using JetBrains.ReSharper.Daemon;
    using JetBrains.ReSharper.Psi.Tree;

    /// <summary>
    /// The <see cref="HighlightingBase"/>
    ///   class is an abstract class used to define highlighting behaviour.
    /// </summary>
    [CLSCompliant(false)]
    public abstract class HighlightingBase : IHighlighting
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="HighlightingBase"/> class.
        /// </summary>
        /// <param name="suggestionName">
        /// Name of the suggestion.
        /// </param>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="toolTip">
        /// The tool tip.
        /// </param>
        protected HighlightingBase(String suggestionName, IElement element, String toolTip)
        {
            ToolTip = toolTip;
            Element = element;
            SuggestionName = suggestionName;
        }

        /// <summary>
        /// Returns true if data (PSI, text ranges) associated with highlighting is valid.
        /// </summary>
        /// <returns>
        /// A <see cref="Boolean"/> value.
        /// </returns>
        public virtual Boolean IsValid()
        {
            return Element.IsValid();
        }

        /// <summary>
        /// Gets the severity.
        /// </summary>
        /// <param name="highlightingName">
        /// Name of the highlighting.
        /// </param>
        /// <returns>
        /// A <see cref="Severity"/> instance.
        /// </returns>
        protected static Severity GetSeverity(String highlightingName)
        {
            return HighlightingSettingsManager.Instance.Settings.GetSeverity(highlightingName);
        }

        /// <summary>
        /// Gets the element.
        /// </summary>
        /// <value>
        /// The element.
        /// </value>
        public IElement Element
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the message for this highlighting to show in tooltip and in status bar 
        ///   (if <see cref="HighlightingAttributeBase.ShowToolTipInStatusBar"/> is <c>true</c>).
        /// </summary>
        /// <value>
        /// The error stripe tool tip.
        /// </value>
        public String ErrorStripeToolTip
        {
            get
            {
                return ToolTip;
            }
        }

        /// <summary>
        /// Gets the offset from the <c>Range.StartOffset</c> to set the cursor to when navigating
        ///   to this highlighting.
        /// </summary>
        /// <remarks>
        /// Usually returns <c>0</c>.
        /// </remarks>
        /// <value>
        /// The navigation offset patch.
        /// </value>
        public Int32 NavigationOffsetPatch
        {
            get
            {
                return 0;
            }
        }

        /// <summary>
        /// Gets the range.
        /// </summary>
        /// <value>
        /// The range.
        /// </value>
        public virtual DocumentRange Range
        {
            get
            {
                return Element.GetDocumentRange();
            }
        }

        /// <summary>
        /// Gets the severity of this highlighting.
        /// </summary>
        /// <value>
        /// The severity.
        /// </value>
        public virtual Severity Severity
        {
            get
            {
                return GetSeverity(SuggestionName);
            }
        }

        /// <summary>
        /// Gets the name of the suggestion.
        /// </summary>
        /// <value>
        /// The name of the suggestion.
        /// </value>
        public String SuggestionName
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the message for this highlighting to show in tooltip and in status bar (if <see cref="HighlightingAttributeBase.ShowToolTipInStatusBar"/> is <c>true</c>)
        ///   To override the default mechanism of tooltip, mark the implementation class with
        ///   <see cref="DaemonTooltipProviderAttribute"/> attribute, and then this property will not be called.
        /// </summary>
        /// <value>
        /// The tool tip.
        /// </value>
        public virtual String ToolTip
        {
            get;
            private set;
        }
    }
}